package com.veetao.api.config;

import javax.annotation.Resource;

import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.MessageListenerContainer;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.core.env.Environment;

import com.veetao.api.msgqueue.ActionHandler;
import com.veetao.api.utils.ConfigUtils;
import com.veetao.api.utils.McpUtils;


/**
 * 
 * @author guohongtao
 * @date 2016年8月2日
 */
@Configuration
public class MessageQueueConfig implements InitializingBean{

    public static final String EXCHANGE   = "spring-boot-exchange";
    public static final String ROUTINGKEY = "spring-boot-routingKey";
    
    private String mqAddresses;
    
    private String mqUserName;
    
    private String mqPassword;
    
    private int mqTimeout;
    
    private String exchangeName;
    
    private String queueName;
    
    private String routeKey;
    
    @Autowired
    private Environment env;
    
    
    @Resource
    private ActionHandler handler;

	@Override
	public void afterPropertiesSet() throws Exception {
		this.mqAddresses = env.getProperty("mq.rabbit.address");
		this.mqUserName = env.getProperty("mq.rabbit.user");
		this.mqPassword = env.getProperty("mq.rabbit.password");
		
		String mqTimeoutStr = env.getProperty("mq.rabbit.timeout");
		if(mqTimeoutStr != null) {
			this.mqTimeout = Integer.parseInt(mqTimeoutStr);
		}
		
		this.exchangeName = env.getProperty("mq.rabbit.exchangeName");
		this.queueName = env.getProperty("mq.rabbit.queueName");
		this.routeKey = env.getProperty("mq.rabbit.routeKey");
	}
    

    @Bean
    public ConnectionFactory connectionFactory() {
    	if(queueName == null) {
    		return new CachingConnectionFactory();
    	}
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setAddresses(mqAddresses);
        connectionFactory.setUsername(mqUserName);
        connectionFactory.setPassword(mqPassword);
        connectionFactory.setConnectionTimeout(mqTimeout);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setPublisherConfirms(true); //必须要设置
        return connectionFactory;
    }
    
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    //必须是prototype类型
    public RabbitTemplate rabbitTemplate() {
    	if(queueName == null) {
    		return new RabbitTemplate(connectionFactory());
//    		return null;
    	}
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        template.setExchange(exchangeName);
        template.setQueue(queueName);
        template.setRoutingKey(routeKey);
        return template;
    }

    private String createSyncConfigQueueName() {
    	return "veetao.queue.cfgSync." + ConfigUtils.getActiveProfile() + "." + McpUtils.getLocalIp();
    }
    
    public static String createSyncConfigExchangeName() {
    	return "veetao.exchange.cfgSync." + ConfigUtils.getActiveProfile();
    }
    
    @Bean
    public RabbitAdmin rabbitAdmin() {
    	if(queueName == null) {
    		return null;
    	}
    	RabbitAdmin admin = new RabbitAdmin(connectionFactory());
    	Queue queue = new Queue(queueName);
    	admin.declareQueue(queue);
    	TopicExchange exchange = new TopicExchange(exchangeName);
    	admin.declareExchange(exchange);
    	admin.declareBinding(BindingBuilder.bind(queue).to(exchange).with(routeKey));
    	
    	/*
    	 * data sync mq configuration
    	 */
    	Queue configSyncQueue = new Queue(createSyncConfigQueueName());
    	TopicExchange configSyncExchange = new TopicExchange(createSyncConfigExchangeName());
    	admin.declareQueue(configSyncQueue);
    	admin.declareExchange(configSyncExchange);
    	admin.declareBinding(BindingBuilder.bind(configSyncQueue).to(configSyncExchange).with(""));
    	
    	return admin;
    }
    
    @Bean
    public MessageListenerContainer listenerContainer() {
    	if(queueName == null) {
    		return null;
    	}
    	SimpleMessageListenerContainer container =
    			new SimpleMessageListenerContainer(connectionFactory());

    	MessageListenerAdapter adapter = new MessageListenerAdapter(handler);
    	container.setMessageListener(adapter);
    	container.setQueueNames(queueName, createSyncConfigQueueName());
    	return container;
    }

    
	public MessageQueueConfig() {
		super();
	}

	public String getMqAddresses() {
		return mqAddresses;
	}

	public void setMqAddresses(String mqAddresses) {
		this.mqAddresses = mqAddresses;
	}

	public String getMqUserName() {
		return mqUserName;
	}

	public void setMqUserName(String mqUserName) {
		this.mqUserName = mqUserName;
	}

	public String getMqPassword() {
		return mqPassword;
	}

	public void setMqPassword(String mqPassword) {
		this.mqPassword = mqPassword;
	}

	public int getMqTimeout() {
		return mqTimeout;
	}

	public void setMqTimeout(int mqTimeout) {
		this.mqTimeout = mqTimeout;
	}


}